package com.hsmpay.mobile.action.account;

import com.hsmpay.common.pojo.user.User;
import com.hsmpay.common.util.DateConvertUtil;
import com.hsmpay.common.util.NumberUtil;
import com.hsmpay.mobile.action.trans.TransBaseAction;
import com.hsmpay.mobile.pojo.other.Settings;
import com.hsmpay.mobile.pojo.trans.TransOrder;
import com.hsmpay.mobile.pojo.trans.TransPriorSettle;
import com.hsmpay.mobile.pojo.user.UserMoney;
import com.hsmpay.mobile.service.account.CashMoneyService;
import com.hsmpay.mobile.service.other.SettingsService;
import com.hsmpay.mobile.service.trans.TransOrderService;
import com.hsmpay.mobile.service.trans.TransPriorSettleService;
import com.hsmpay.mobile.service.user.UserMoneyService;
import com.hsmpay.utils.system.ConConfig;

import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import java.util.*;

/**
 * 公众号网页端提现action
 */
@Controller("oACashMoneySafeAction")
@Scope("prototype")
public class OACashMoneySafeAction extends TransBaseAction{

    private static final long serialVersionUID = -420943717050046752L;
    private static Logger log = Logger.getLogger(OACashMoneySafeAction.class);

    @Resource(name = "cashMoneyService")
    private CashMoneyService<TransOrder, Long> cashMoneyService;
    @Resource(name = "userMoneyService")
    private UserMoneyService<UserMoney, Long> userMoneyService;
    @Resource(name = "transOrderService")
    private TransOrderService<TransOrder, Long> transOrderService;
    private TransOrder order;
    private TransPriorSettle transPriorSettle;
    @Resource(name = "transPriorSettleService")
    private TransPriorSettleService<TransPriorSettle, Long> transPriorSettleService;
    @Resource(name="settingsService")
    protected SettingsService<Settings, Long> settingsService;

    private String orderNum;//订单编号
    //static double CashMoneyFee = 2.0;//提现手续费
    static double CashMoneyFee = Double.parseDouble(ConConfig.getAttribute("CASH_MONEY_FEE"));

    /**
     * 提现
     *
     * @return
     * @throws Exception
     */
    public String cashMoney() throws Exception {
        log.debug("--- OfficialAccPay cashMoney() start ---");

        userId = Long.valueOf(getRequest().getParameter("userId"));
        String orderNum = getRequest().getParameter("orderNum");
        Double cashMoneyFee = Double.valueOf(getRequest().getParameter("cashMoneyFee"));
        Double cashMoney = Double.valueOf(getRequest().getParameter("cashMoney"));

        functionKey = "CASHMONEY";
        log.debug("functionKey = " + functionKey);
        log.debug("userId = " + userId);
        log.debug("cashMoney = " + cashMoney);
        log.debug("cashMoneyFee = " + cashMoneyFee);
        log.debug("orderNum = " + orderNum);

        if (null == userId) {
            log.info("提现时, 传入参数userId为空");
            sendWeChatErrorMsg("6001", "userId");
            return null;
        }
        if (null == cashMoney) {
            log.info("提现时, 传入参数cashMoney为空");
            sendWeChatErrorMsg("6001", "cashMoney");
            return null;
        }
        if (null == cashMoneyFee) {
            log.info("提现时, 传入参数cashMoneyFee为空");
            sendWeChatErrorMsg("6001", "cashMoneyFee");
            return null;
        }
        if (StringUtils.isBlank(functionKey)) {
            log.info("提现时, 传入参数functionKey为空");
            sendWeChatErrorMsg("6001", "functionKey");
            return null;
        }

        try {
            Date date = new Date();

            User user = userService.getUserById(userId);

            if (!checkWeChartPIV(functionKey)) {
                log.warn("提现时, 银行接口暂停使用！");
                return null;
            }
            if (cashMoney <= CashMoneyFee) {
                log.info("提现错误，提现金额不能小于" + CashMoneyFee + " 元！");
                sendWeChatErrorMsg("6081", CashMoneyFee + "");
                return null;
            }

            if (null != user) {
                //判断 绑定银行卡
                if (null == user.getBankStatus() || 3 == user.getBankStatus()) {
                    sendWeChatErrorMsg("6041");
                    return null;
                } else if (2 == user.getBankStatus()) {
                    sendWeChatErrorMsg("6042");
                    return null;
                } else if (0 == user.getBankStatus()) {//0:认证失败 1:认证通过 2:审核中 3:未申请认证 DEFAULT 3
                    sendWeChatErrorMsg("6043");
                    return null;
                }

                //判断用户 结算状态
                if (user.getClearStatus() == null || user.getClearStatus().intValue() != 1) {
                    String message = "用户存在违法，请跟管理员联系！";
                    sendWeChatErrorMsg(message);
                    return null;
                }

                //查询订单
                order = new TransOrder();
                order.setOrderNum(orderNum);
                order = transOrderService.searchEntity(order);
                transPriorSettle = new TransPriorSettle();
                transPriorSettle.setOrderNum(orderNum);
                transPriorSettle = transPriorSettleService.searchEntity(transPriorSettle);
                if (null == order) {
                    log.warn("安全提现时, 不存在该订单！");
                    sendWeChatErrorMsg("6086");
                    return null;
                }
                if (1 != order.getOrderTypeId().intValue()) {//订单不是收款订单
                    log.warn("安全提现时, 订单不是收款订单！");
                    sendWeChatErrorMsg("6087");
                    return null;
                }
                if (1 != order.getStatus().intValue()) {//收款订单不是交易成功的订单
                    log.warn("提现失败，收款订单不是交易成功的订单！");
                    sendWeChatErrorMsg("6092");
                    return null;
                }

                double chargeAmount = order.getChargeAmount();
                if (chargeAmount != NumberUtil.roundF2((cashMoneyFee + cashMoney)) && chargeAmount != cashMoney) {//金额不相等
                    log.warn("安全提现时, 传入提现金额与手续费不符！");
                    sendWeChatErrorMsg("6088");
                    return null;
                }
                if (!checkOrderTime(order.getCreateDate())) {
                    String dateStr = DateConvertUtil.dateString(order.getCreateDate());
                    log.warn("提现失败, 该订单只能在 " + dateStr + " 22:40:00 前执行提现，对于不能提现的交易，请等待T+1结算！");
                    sendWeChatErrorMsg("6090");
                    return null;
                }
                if (null != order.getCashOrderNum()) {
                    TransOrder cashOrder = new TransOrder();
                    cashOrder.setOrderNum(order.getCashOrderNum());
                    cashOrder = transOrderService.searchEntity(cashOrder);
                    if (null == cashOrder || cashOrder.getStatus().intValue() != 0) {
                        log.warn("安全提现失败，不允许重复提现！");
                        sendWeChatErrorMsg("6091");
                        return null;
                    }
                }

                //金额是否足够
                boolean isZhugou = userMoneyService.moneyTheAdequacy(userId, chargeAmount, 1);
                if (!isZhugou) {
                    log.info("提现错误，金额不足！");
                    sendWeChatErrorMsg("6082", chargeAmount + "");
                    return null;
                }

                TransOrder transOrder = new TransOrder();
                transOrder.setOrderNum(getOrderNumByDate(date));
                transOrder.setOrderTypeId(8l);//提现
                transOrder.setUserId(userId);
                transOrder.setTransMoney(chargeAmount);

                transOrder.setFeeMoney(cashMoneyFee);//fee);//手续费
                transOrder.setBrokerage(0.0000);//brokerage);
                transOrder.setDealerBrokerage(0.0000);
                transOrder.setChargeAmount(cashMoney);
                transOrder.setRootCategory("账务管理");
                transOrder.setCategory("提现");
                transOrder.setObjectiveName(user.getCardholder());//对方姓名
                transOrder.setObjectiveCard(user.getBankCard());//对方银行卡
                transOrder.setObjectiveOpBank(user.getOpeningBank());//对方银行

                transOrder.setStatus(2);
                transOrder.setClearing(0);//结算状态 0未结算 1结算
                transOrder.setDescription("系统结算");//交易详情
                transOrder.setCreateDate(date);
                transOrder.setUpdateLongTime(date.getTime());

                transOrder.setObjectiveBBank(user.getBranchesBank());//对方。银行支行
                transOrder.setObjectiveBBProvince(user.getBBankProvince());
                transOrder.setObjectiveBBCity(user.getBBankCity());
                transOrder.setObjectiveMobile(user.getMobile());//对方手机号
                transOrder.setObjectiveBBankCode(user.getBranchesBankCode());
                transOrder.setObjectiveAccBankCode(user.getAccBankCode());
                transOrder.setTerminalTypeId(user.getTerminalTypeId());
                transOrder.setRoleId(2l);
                transOrder.setOrgOrderNum(order.getOrderNum());//原订单编号
                transOrder.setFeeRate(user.getCashRate());//订单费率
                transOrder.setFdMaxFee(0.00);//用户封顶最高
                transOrder.setFdMinFee(2.00);//用户封顶最低
                transOrder.setClientType(1);

                //修改原订单
                transOrderService.updateCashOrderByNum(order.getOrderNum(), transOrder.getOrderNum());

                //判断 机构预存款
                int flag = cashMoneyService.weChartCashMoneySafe(transOrder);

                if (flag == 1) {
                    String reqMsg = "提现成功，一小时内自动结算到您绑定的银行卡账号中！";
                    JSONObject result = new JSONObject();
                    result.put("code", "0000");
                    result.put("msg", reqMsg);
                    sendWeChatMsg(result.toString());
                } else if (flag == 2) {//预存款不足
                    //修改原订单
                    transOrderService.updateCashOrderByNum(order.getOrderNum(), "");
                    sendWeChatErrorMsg("6084");
                }
            } else {
                log.warn("提现时, 用户Id=" + userId + " 对应的用户不存在!");
                sendWeChatErrorMsg("6012", userId + "");
            }
        } catch (Exception e) {
            //修改原订单
            transOrderService.updateCashOrderByNum(order.getOrderNum(), "");
            e.printStackTrace();
            throw e;
        }
        return null;
    }

    /**
     * 提现检测
     *
     * @return
     * @throws Exception
     */
    public String checkCashMoney() throws Exception {
        log.debug("--- OfficialAccPay checkCashMoney() start ---");
        User user = (User) getSession().getAttribute("SESSION_USER");
        orderNum = getRequest().getParameter("orderNum");

        if(null == user){
            log.debug("提现时, 用户不存在!");
            sendWeChatErrorMsg("6001","user");
            return null;
        }

        if (null != user.getId()){
            userId = user.getId();
        }

        functionKey = "CASHMONEY";

        log.debug("userId = " + userId);
        log.debug("functionKey = " + functionKey);
        log.debug("orderNum = " + orderNum);

        if (null == userId) {
            log.info("提现时, 传入参数userId为空");
            sendWeChatErrorMsg("6001", "userId");
            return null;
        }
        if (StringUtils.isBlank(functionKey)) {
            log.info("提现时, 传入参数functionKey为空");
            sendWeChatErrorMsg("6001", "functionKey");
            return null;
        }
        if (StringUtils.isBlank(orderNum)) {
            log.info("提现时, 传入参数orderNum为空");
            sendWeChatErrorMsg("6001", "orderNum");
            return null;
        }

        try {
            Date date = new Date();

            if (!checkWeChartPIV(functionKey)) {
                log.warn("提现时, 银行接口暂停使用！");
                return null;
            }

            if (null != user) {

                //判断用户 结算状态
                if (user.getClearStatus() == null || user.getClearStatus().intValue() != 1) {
                    String message = "用户存在违法，请跟管理员联系!";
                    sendWeChatMsg(message);
                    return null;
                }

                //查询订单
                order = new TransOrder();
                order.setOrderNum(orderNum);
                order = transOrderService.searchEntity(order);
                transPriorSettle = new TransPriorSettle();
                transPriorSettle.setOrderNum(orderNum);
                transPriorSettle = transPriorSettleService.searchEntity(transPriorSettle);
                if (null == order) {//不存在该订单
                    log.warn("安全提现时, 不存在该订单！");
                    sendWeChatErrorMsg("6086");
                    return null;
                }
                if (null != order.getOrderTypeId() && 11l == order.getOrderTypeId()){
                    log.warn("零费率订单" + orderNum + "不允许提现");
                    sendWeChatErrorMsg("6111");
                    return null;
                }
                if (1 != order.getOrderTypeId().intValue()) {//订单不是收款订单
                    log.warn("安全提现时, 订单不是收款订单！");
                    sendWeChatErrorMsg("6087");
                    return null;
                }
                if (!checkOrderTime(order.getCreateDate())) {
                    String dateStr = DateConvertUtil.dateString(order.getCreateDate());
                    log.warn("提现失败, 该订单只能在 " + dateStr + " 22:40:00 前执行提现，对于不能提现的交易，请等待T+1结算！");
                    sendWeChatErrorMsg("6090");
                    return null;
                }
                if (null != order.getCashOrderNum()) {
                    TransOrder cashOrder = new TransOrder();
                    cashOrder.setOrderNum(order.getCashOrderNum());
                    cashOrder = transOrderService.searchEntity(cashOrder);
                    if (null != cashOrder && cashOrder.getStatus().intValue() != 0) {
                        log.warn("安全提现失败，不允许重复提现！");
                        sendWeChatErrorMsg("6091");
                        return null;
                    }
                }

                double transMoney = order.getTransMoney();
                double feeMoney = order.getFeeMoney();
                double chargeAmount = order.getChargeAmount();
                double cashMoneyFee = CashMoneyFee + NumberUtil.roundF2(transMoney * user.getCashRate());//提现手续费
                double cashMoney = NumberUtil.roundF2((chargeAmount - cashMoneyFee));//NumberUtil.numFormatToNum((chargeAmount*(1-cashMoneyFeeRate)));
                if (cashMoney <= 0) {
                    log.info("提现错误，提现金额不能小于" + CashMoneyFee + " 元！");
                    sendWeChatErrorMsg("6081", CashMoneyFee + "");
                    return null;
                }

                //说明与标题
                Settings settings = settingsService.getSettingsByFk("NORMAL_INSTRUCTIONS_AND_TITLE");
                String reqMsg = settings.getMainValue();
                reqMsg = reqMsg.replace("提现手续费费率", "提现手续费费率("+user.getCashRate()+")");
                JSONObject result = new JSONObject();
                result.put("cashMoneyFeeRate", (null == user.getCashRate()));//提现手续费费率
                result.put("cashMoney", cashMoney);//提现金额
                result.put("cashMoneyFee", cashMoneyFee);//提现手续费
                result.put("transMoney", transMoney);//收款交易金额
                result.put("feeMoney", feeMoney);//收款交易手续费
                result.put("reqCode", "0000");
                result.put("reqMsg", reqMsg);//T+0提现说明
                result.put("title",settings.getValue2());//T+0提现标题
                result.put("userId",user.getId());
                sendWeChatMsg(result.toString());

            } else {
                log.warn("提现时, 用户Id=" + userId + " 对应的用户不存在!");
                sendWeChatErrorMsg("6012", userId + "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return null;
    }

    /**
     * 检查订单时间是否可以提现
     *
     * @param orderDate
     * @return
     * @throws Exception
     */
    private boolean checkOrderTime(Date orderDate) throws Exception {
        Date tempDate = DateConvertUtil.getSpecifiedDayBefore(order.getCreateDate());
        Date startDate = DateConvertUtil.stringDateTime(DateConvertUtil.dateString(tempDate) + " 23:00:00");//昨天 23：00：00
        Date stopDate = DateConvertUtil.stringDateTime(DateConvertUtil.dateString(orderDate) + " 22:40:00");//今天 22：40：00

        Date date = new Date();

        if (date.getTime() < startDate.getTime()) {
            return false;
        } else if (date.getTime() > stopDate.getTime()) {
            return false;
        }
        return true;
    }

}
